[ 롤모임 운영일지 ] - 22. 내 커밋의 94%에는 같은 동료의 이름이 있다

이 서비스의 커밋 855개 중 806개(94%)에는 Co-Authored-By: Claude가 붙어 있다. 석 달 반 동안 사실상 모든 코드를 AI와 같이 썼다는 뜻이다. 이렇게 말하면 보통 “프롬프트를 어떻게 쓰세요?”라는 질문이 돌아온다. 그런데 실제로 해보니, AI와 함께 개발하는 일의 본체는 프롬프트가 아니었다. 이번 편은 그 얘기다 — 이 시리즈에 기록해온 사고들을 “AI와의 협업”이라는 축으로 다시 꿰어보면 뭐가 보이는지.


1. 동료는 세션마다 기억을 잃는다

AI가 낸 사고들을 돌아보면 패턴이 하나 있다. 몰라서 낸 사고가 아니라, 이 코드베이스의 암묵지를 몰라서 낸 사고라는 것.

  • soft-delete 전역 확장이 deletedAt 없는 모델에까지 필터를 주입해 500 에러 — 같은 함정으로 6월에 한 번, 7월에 또 한 번.
  • 크로스테넌트 누출 — Prisma Extension이 자동으로 groupId를 끼워 넣는다는 걸 아는 상태에서, raw SQL은 그 대상이 아니라는 것까지는 챙기지 못했다.

둘 다 “Prisma를 모르는” 실수가 아니다. “이 레포에서는 soft-delete가 전역 확장으로 걸려 있고, 테넌트 격리는 Extension 방식이라 raw SQL이 사각지대”라는, 어디에도 안 적혀 있던 이 집만의 규칙을 몰랐던 것이다. 그리고 이건 AI만의 문제도 아니다 — 사람 신입이 와도 똑같이 밟았을 함정이다. 차이가 있다면, AI 동료는 세션이 끝날 때마다 기억이 리셋되니 매일이 입사 첫날이라는 점이다.

2. 그래서 온보딩 문서를 계속 고쳐 쓴다

그 결론으로 레포 루트에 AGENTS.md라는 파일이 생겼다. AI가 세션을 시작할 때마다 읽는 35줄짜리 문서인데, 내용이 좀 특이하다. 아키텍처 설명이 아니라 사고 이력이 적혀 있다.

// AGENTS.md (일부)
- **절대 로컬 미커밋 코드를 CLI로 직접 배포하지 말 것.** 2026-06-09에
  미커밋(gitDirty) 상태로 CLI 배포한 탓에 git≠운영이 됐고, 표준 절차가
  운영 코드를 덮는 사고가 났다. 항상 **커밋 → 푸시 → 배포** 순서.
- **`prisma db push` 전 반드시 dry-run으로 drop 경고 확인**
  (로컬 schema가 prod와 어긋나면 무관한 테이블/컬럼을 지우려 함).

1편에 기록했던 배포 사고들이 날짜째로 들어가 있다. 사고가 날 때마다 이 문서에 한 줄이 늘어난다 — 사람 팀이 포스트모템을 쓰고 온보딩 문서에 반영하는 것과 정확히 같은 동작이다. 혼자 개발할 때는 귀찮아서 안 하던 일인데, 기억을 잃는 동료와 일하게 되니 안 할 수가 없게 됐다. (참고로 레포의 CLAUDE.md@AGENTS.md 한 줄뿐이다 — 도구마다 읽는 파일 이름이 달라서, 내용은 한 곳에 두고 링크만 걸었다.)

재미있는 건, 이 문서가 쌓일수록 나한테도 좋다는 것이다. 석 달 전의 나도 세부 사항은 다 잊어버린 사람이라, 결국 나도 이 문서의 독자다.

3. 반복 작업은 런북으로 — 커맨드와 스킬

AGENTS.md가 “항상 알아야 하는 규칙”이라면, 특정 작업의 절차는 다른 층에 둔다. 이 블로그 게시가 좋은 예다.

/devlog라고 치면 커맨드 파일이 먼저 인자를 해석한다 — “/devlog 어제 고친 N+1 버그”처럼 주제를 주면 그 주제만 다루고, 범위를 임의로 넓히지 않는다. 그리고 커맨드는 143줄짜리 스킬 문서를 불러온다. 거기에는 블로그 저장소를 pull하는 것부터 기존 시리즈의 파일명 규칙·문체 파악, front matter 형식, 커밋 전 보안 스캔(grep 패턴까지 통째로 적혀 있다), push 전 사용자 확인까지 — 절차 전체가 들어 있다.

// ~/.claude/commands/devlog.md (일부)
1. 모르는 내용을 지어내지 않는다 — 코드/git 로그/대화에서 실제로 확인한 것만 쓴다.
3. 커밋 전 반드시 보안 스캔(실제 URL/키/IP/커넥션 스트링 여부)을 하고, 걸리면 진행하지 않는다.
4. master push는 매번 사용자 확인을 받은 뒤에 한다.

둘을 나눈 이유는 사람 팀의 문서와 같다. 온보딩 문서(AGENTS.md)는 매 세션 통째로 읽히니 얇게 유지하고, 작업별 런북(스킬)은 그 작업을 할 때만 꺼내 읽게 한다. 블로그를 쓸 때만 블로그 절차가 필요하니까.

효과는 생각보다 크다. 예전에는 “커밋 전에 민감정보 확인해야지”를 내가 기억해야 했는데, 절차가 문서에 박히고 나서는 기억이 아니라 실행의 문제가 됐다.

4. 검증은 사람이 못 따라간다 — 구조가 한다

AI와 일하면 코드 생산 속도가 리뷰 속도를 추월하는 날이 온다. 제일 심했던 4월 15일에는 하루에 60커밋, 7천 줄이 추가됐다. 이런 날 리뷰는 읽기가 아니라 훑기가 된다.

하지만 솔직히 말하면 양은 절반의 문제다. 더 뼈아픈 쪽은 — 이 시리즈에 기록한 사고들이 전부 내 리뷰를 통과하고 프로덕션에 나갔다는 사실이다. soft-delete 500도, 0점 입찰이 사라지던 버그도, 크로스테넌트 누출도 diff를 보고 머지한 코드에서 났다. 눈은 문법과 로직의 그럴듯함을 읽지, “이 집의 불변식을 지켰는가”를 검사하지 못한다. 그래서 검증을 구조에 맡기는 쪽으로 조금씩 옮겨왔다.

  • 순수함수 추출 + 단위테스트. 경매 입찰 검증처럼 사고가 반복되는 로직은 순수함수로 뽑아 테스트를 깔았다. 지금 packages/api에는 이런 테스트 파일이 24개 있다. AI가 어디를 고치든, 이 로직들이 깨지면 즉시 드러난다.
  • 정답지가 있는 검증. Glicko-2 구현은 내가 수식을 검산할 수 없으니, 논문에 실린 검증 벡터를 그대로 테스트로 만들었다. 내가 못 믿는 건 내 눈이지 논문이 아니니까.
  • 배포 전 코드리뷰. 출시 직전 리뷰에서 falsy zero, 캡 오버플로 같은 7건이 한꺼번에 걸린 적이 있다. 리뷰가 없었으면 전부 유저가 발견했을 버그다.
  • 어드민 기능검증 탭. 시즌패스처럼 상태가 복잡한 기능은 배포 후 실데이터로 미션 배정·진행도를 눈으로 확인할 수 있는 화면을 아예 만들어뒀다.

공통점은 하나다. “AI를 믿는다/안 믿는다”의 문제로 두지 않고, 믿음이 필요 없는 구조를 만드는 것. 이건 사실 AI가 아니라 사람 팀원이어도 똑같이 해야 하는 일들이다.

5. 끝까지 안 넘어가는 일

석 달 반 동안 역할 분담은 자연스럽게 정리됐다. 코드는 대부분 같이 쓴다. 하지만 뭘 만들지, 뭘 만들지 않을지, 언제 배포할지, 사고 났을 때 단톡방에 뭐라고 쓸지는 넘어가지 않았다. 넘길 수 없어서가 아니라, 넘기면 이 서비스가 내 것이 아니게 되기 때문이다.

그리고 이 시리즈도 그 일 중 하나다. 사고를 겪고, 뭐가 문제였는지 정리하고, 같은 사고가 반복되지 않게 문서에 박아 넣는 것 — 그 기록의 절반은 AGENTS.md로 가서 동료의 기억이 되고, 나머지 절반은 이 블로그로 와서 내 기억이 된다.

정리

  • AI와의 협업에서 사고의 원인은 대부분 능력이 아니라 컨텍스트였다. 코드베이스의 암묵지를 문서로 만드는 것이 프롬프트 잘 쓰는 것보다 훨씬 효과가 컸다.
  • 문서에도 층위가 있다. 항상 읽히는 규칙(AGENTS.md)은 얇게, 작업별 절차는 커맨드와 스킬로 — 온보딩 문서와 런북의 관계와 같다. 절차가 문서에 박히면 지키는 게 기억이 아니라 실행의 문제가 된다.
  • 검증은 눈이 아니라 구조로: 순수함수 테스트 24개, 논문 검증 벡터, 배포 전 리뷰, 기능검증 탭.
  • 그 결과가 흥미롭다 — 포스트모템, 온보딩 문서, 테스트, 리뷰. 좋은 팀이 원래 하는 일들을, 혼자가 된 뒤에야 진짜로 하게 됐다. 동료가 사람이 아니게 되고 나서야.

댓글